const TelegramBot = require("node-telegram-bot-api");
const config = require("./config.json");
const bot = new TelegramBot(config.telegramBotToken, { polling: true });

if (process.env.NODE_ENV === "development") {
    // To test if the bot is working.
    bot.onText(/\/echo (.+)/, function (msg, match) {
        const chatId = msg.chat.id;
        const resp = match[1];
        bot.sendMessage(chatId, resp);
    });
}

// Enable notification for the specified git repository.
bot.onText(/\/enable (.+)/, function (msg, match) {
    // Check for existence in MongoDB
    const git = match[1];
    const db = require("./db");
    db.getPassword(msg.chat.id, git).then(async function (chat) {
        if (chat) {
            bot.sendMessage(msg.chat.id, `Notification has already been enabled! Post url is: \n${config.baseUrl}/gitee\nPassword is: \n\`${chat.password}\``, {
                parse_mode: "Markdown",
                reply_to_message_id: msg.message_id
            });            
        } else {
            const uuid = require("uuid/v4");
            const password = uuid();
            await db.saveChat(msg.chat.id, git, password);
            bot.sendMessage(msg.chat.id, `Notification is enabled! Post url is: \n${config.baseUrl}/gitee\nPlease set password to: \n\`${password}\``, {
                parse_mode: "Markdown",
                reply_to_message_id: msg.message_id
            });
        }
    }).catch(function (err) {
        bot.sendMessage(msg.chat.id, "Sorry but an error has occurred.", {
            reply_to_message_id: msg.message_id
        });
    });
});

/**
 * Generate user-friendly string describing pushing.
 * @param {object} obj Push object received from gitee server.
 * @param {object} obj.user The user who pushed commits.
 * @param {string} obj.user.name The name of the user.
 * @param {string} obj.user.url The home page of the user.
 * @param {number} obj.commitCount The number of commits.
 * @param {object} obj.repository The repository to which commits have been pushed.
 * @param {string} obj.repository.name The name of the repository.
 * @param {string} obj.repository.url The home page of the repository.
 */
function getPushMessage(obj) {
    return `[${obj.user.name}](${obj.user.url}) pushed ${obj.commitCount} commits to [${obj.repository.name}](${obj.repository.url}).`;
}

/**
 * Generate user-friendly string describing commits.
 * @param {object[]} commits The commits that have been pushed to the server.
 * @param {string} commits.message The commit message.
 * @param {string} commits.url The url of commit.
 */
function flattenCommits(commits) {
    return commits.map(function (commit) {
        return `[${commit.message}](${commit.url})`;
    }).join("\n");
}

module.exports = {
    /**
     * Send a notification to the specified telegram chat.
     * @param {number} chatId Telegram chat id.
     * @param {object} obj Push object received from gitee server.
     * @param {object} obj.user The user who pushed commits.
     * @param {string} obj.user.name The name of the user.
     * @param {string} obj.user.url The home page of the user.
     * @param {number} obj.commitCount The number of commits.
     * @param {object[]} obj.commits The commits that have been pushed to the server.
     * @param {string} commits.message The commit message.
     * @param {string} commits.url The url of commit.
     * @param {object} obj.repository The repository to which commits have been pushed.
     * @param {string} obj.repository.name The name of the repository.
     * @param {string} obj.repository.url The home page of the repository.
     */
    push (chatId, obj) {
        return bot.sendMessage(chatId, `${getPushMessage(obj)}\n${flattenCommits(obj.commits)}`, {
            parse_mode: "Markdown",
            disable_web_page_preview: true
        });
    }
};